<!--
 * @Description:
 * @Version: 1.0
 * @Autor: haozhuang
 * @Date: 2020-05-07 10:32:05
 * @LastEditors: haozhuang
 * @LastEditTime: 2020-05-08 17:09:05
 -->
<template>
  <div v-divDrag class="catalog">
    <h3 class="title">
      内容目录
      <img
        src="@/assets/project/add.png"
        alt=""
        @click="
          () => {
            selectedNode = null;
            open('addFolder');
          }
        "
      >
    </h3>
    <el-scrollbar>
      <el-tree
        ref="tree"
        :data="folderList"
        :props="defaultProps"
        node-key="id"
        @node-click="handleNodeClick"
        @node-drop="handleDrop"
        :allow-drop="allowDrop"
        draggable
      >
        <span
          slot-scope="{ node }"
          class="custom-tree-node"
          :class="{ 'tree-node-first': node.level === 1 }"
        >
          <i class="el-icon-tickets"/>
          <span>{{ node.label }}</span>
          <i class="el-icon-more" style="font-size:18px" @click.prevent="handleShow($event)"/>
        </span>
      </el-tree>
    </el-scrollbar>

    <uploader ref="uploader" :selected-node="selectedNode"/>
    <v-contextmenu ref="contextmenu">
      <v-contextmenu-submenu>
        <span slot="title">
          <span class="el-icon-circle-plus-outline"/>新建</span>
        <v-contextmenu-item
          @click="open('addFile')"
        >文档文件
        </v-contextmenu-item>
        <v-contextmenu-item
          @click="open('mindMapAdd')"
        >思维导图
        </v-contextmenu-item>
        <v-contextmenu-item
          @click="open('addFolder')"
        >文件夹
        </v-contextmenu-item>
      </v-contextmenu-submenu>
      <v-contextmenu-submenu>
        <span slot="title"><span class="el-icon-upload2"/>上传</span>
        <v-contextmenu-item @click="uploadFile">文档文件</v-contextmenu-item>
        <v-contextmenu-item @click="uploadFolder">文件夹</v-contextmenu-item>
      </v-contextmenu-submenu>
      <v-contextmenu-item @click="open('update')">
        <span class="el-icon-edit"/>重命名
      </v-contextmenu-item>
      <!--   <v-contextmenu-item>
        <span class="el-icon-document-copy" />复制
      </v-contextmenu-item>
      <v-contextmenu-item>
        <span class="el-icon-delete" />粘贴
      </v-contextmenu-item> -->
      <v-contextmenu-item @click="folderDelete">
        <span class="el-icon-delete"/>删除
      </v-contextmenu-item>
      <!--  <v-contextmenu-item>
        <span class="el-icon-delete" />自定义
      </v-contextmenu-item> -->
    </v-contextmenu>

    <div
      class="drag-line"
      style="top: 0px; right: -4px; width: 7px; height: 100%; position: absolute; z-index: 1;"
    />
  </div>
</template>

<script>
  import {
    folderTree,
    folderAdd,
    folderRename,
    folderDelete,
    folderSort
  } from '@/api/folder'
  import { fileNodeAdd, mindMapAdd } from '@/api/file'
  import { folderJudge1, fileJudge1, mindMapJudge1 } from './judge'
  import { showContextmenu, transformTozTreeFormat } from '@/utils/index'
  import uploader from './uploader'

  export default {
    name: 'Priject',
    components: { uploader },
    data() {
      return {
        folderList: [],
        defaultProps: {
          children: 'children',
          label: 'name'
        },
        selectedNode: {},
        instance: null,
        done: null,
        originFolderData: []
      }
    },
    computed: {},
    created() {
      this.folderTree()
    },
    methods: {
      folderTree() {
        folderTree()
          .then(result => {
            const { data } = result
            this.originFolderData = data
            this.folderList = data === '[]' ? [] : transformTozTreeFormat(data, 'id', 'parentId')
          })
          .catch(err => {
            console.log(err)
          })
      },
      folderAdd() {
        if (this.selectedNode !== null && this.selectedNode.isUpdate === 0) {
          this.$message('无操作权限')
          return false
        }
        const name = this.instance.inputValue
        const parentId = this.selectedNode ? this.selectedNode.id : 0
        let level = this.selectedNode ? this.selectedNode.level : -1
        level++
        folderAdd(parentId, name, level)
          .then(result => {
            const { data } = result
            if (this.selectedNode) {
              this.$refs.tree.append(data, this.selectedNode)
            } else {
              this.folderList.push(data)
              this.$forceUpdate()
            }
            this.instance.confirmButtonLoading = false
            this.done()
          })
          .catch(err => {
            this.instanceReset()
            console.log(err)
          })
      },
      folderRename() {
        const name = this.instance.inputValue
        const parentId = this.selectedNode.parentId
        const folderId = this.selectedNode.id
        folderRename(parentId, name, folderId)
          .then(result => {
            this.selectedNode.name = name
            this.instance.confirmButtonLoading = false
            this.done()
          })
          .catch(err => {
            this.instanceReset()
            console.log(err)
          })
      },
      folderDelete() {
        if (this.selectedNode.isDelete === 0) {
          this.$message('无操作权限')
          return false
        }
        folderDelete(this.selectedNode.id)
          .then(result => {
            this.removeTreeNode()
          })
          .catch(err => {
            console.log(err)
          })
      },
      removeTreeNode() {
        const parent = this.$refs.tree.getNode(this.selectedNode).parent
        const children = parent.data.children || parent.data
        const index = children.findIndex(d => d.id === this.selectedNode.id)
        children.splice(index, 1)
      },
      open(type) {
        if (this.selectedNode !== null && this.selectedNode.isUpdate === 0) {
          this.$message('无操作权限')
          return false
        }
        let title = ''
        let inputValue = ''
        switch (type) {
          case 'addFolder':
            title = '添加文件夹'
            break
          case 'update':
            title = '修改文件夹'
            inputValue = this.selectedNode.name
            break
          case 'addFile':
            title = '添加文件'
            break
          case 'mindMapAdd':
            title = '添加文件'
            break
        }

        this.$prompt('', title, {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          inputValue,
          closeOnClickModal: false,
          beforeClose: async(action, instance, done) => {
            if (action === 'confirm') {
              console.log(instance)
              instance.confirmButtonLoading = true
              instance.confirmButtonText = '执行中...'
              this.instance = instance
              this.done = done

              const name = this.instance.inputValue
              if (type === 'addFolder') {
                const parentId = this.selectedNode
                  ? this.selectedNode.parentId
                  : 0
                const is = await folderJudge1(parentId, name)
                console.log(is)
                is ? this.folderAdd() : this.instanceReset()
              } else if (type === 'update') {
                const parentId = this.selectedNode
                  ? this.selectedNode.parentId
                  : 0
                const is = await folderJudge1(parentId, name)
                console.log(is)
                is ? this.folderRename() : this.instanceReset()
              } else if (type === 'addFile') {
                const parentId = this.selectedNode ? this.selectedNode.id : 0
                const is = await fileJudge1(parentId, name)
                console.log(is)
                is ? this.fileNodeAdd() : this.instanceReset()
              } else if (type === 'mindMapAdd') {
                const parentId = this.selectedNode ? this.selectedNode.id : 0
                const is = await mindMapJudge1(parentId, name)
                console.log(is)
                is ? this.mindMapAdd() : this.instanceReset()
              }
            } else {
              done()
            }
          }
        })
      },
      fileNodeAdd() {
        const name = this.instance.inputValue
        const folderId = this.selectedNode.id
        fileNodeAdd(folderId, name)
          .then(result => {
            this.instance.confirmButtonLoading = false
            this.$parent.selectedFolder(this.selectedNode)
            this.done()
          })
          .catch(err => {
            console.log(err)
          })
      },
      mindMapAdd() {
        const name = this.instance.inputValue
        const folderId = this.selectedNode.id
        mindMapAdd(folderId, name)
          .then(result => {
            this.$parent.selectedFolder(this.selectedNode)
            this.instance.confirmButtonLoading = false
            this.done()
          })
          .catch(err => {
            console.log(err)
          })
      },
      uploadFile() {
        this.$refs.uploader.uploadFile()
      },
      uploadFolder() {
        this.$refs.uploader.uploadFolder()
      },
      instanceReset() {
        this.instance.confirmButtonLoading = false
        this.instance.confirmButtonText = '确定'
      },
      handleNodeClick(data, Node) {
        this.selectedNode = data
        this.$emit('selectedFolder', data)
        this.$store.commit('index/set_authority', {
          isLook: data.isLook,
          isUpdate: data.isUpdate,
          isDelete: data.isDelete
        })
      },
      handleShow(event) {
        showContextmenu(this.$refs.contextmenu, event)
      },
      allowDrop(draggingNode, dropNode, type){
        if (draggingNode.data.level === dropNode.data.level) {
          //aboveId是父节点id
          if (draggingNode.data.aboveId === dropNode.data.aboveId) {
            return type === 'prev' || type === 'next'
          }
        } else {
          // 不同级进行处理
          return false
        }
      },
      // 拖拽事件 参数依次为：被拖拽节点对应的 Node、结束拖拽时最后进入的节点、被拖拽节点的放置位置（before、after、inner）、event
      handleDrop(draggingNode, dropNode, dropType, ev) {
        if (dropType === 'inner') {
          this.$message.error('只支持同级别移动')
          return
          // this.$message.warning('只支持同级别移动!');
          // return
        }
        let paramData = []
        // 当拖拽类型不为inner,说明只是同级或者跨级排序，只需要寻找目标节点的父ID，获取其对象以及所有的子节点，并为子节点设置当前对象的ID为父ID即可
        // 当拖拽类型为inner，说明拖拽节点成为了目标节点的子节点，只需要获取目标节点对象即可
        let data = dropType !== 'inner' ? dropNode.parent.data : dropNode.data
        let nodeData = dropNode.level === 1 && dropType !== 'inner' ? data : data.children
        // 设置父ID,当level为1说明在第一级，pid为空
        nodeData.forEach(element => {
          element.pid = dropNode.level === 1 ? '' : data.id
        })
        const parentArr = dropNode.parent.childNodes
        if (parentArr !== null) {
          let beforeId = 0
          let endId = 0
          let currentId = draggingNode.data.id
          let before = 0
          let end = 0
          const current = this.getPositionById(parentArr, currentId)
          if (current === 0) {
            before = -1
            end = current + 1
          } else if (current !== 0) {
            before = current - 1
            end = current + 1
          }
          if (current === parentArr.length - 1) {
            end = -1
          }
          beforeId = before === -1 ? 0 : parentArr[before].data.id
          endId = end === -1 ? 0 : parentArr[end].data.id
          // console.log(beforeId, currentId, endId)
          folderSort(currentId, beforeId, endId)
            .then(result => {
              console.log(result)
            })
            .catch(err => {
              console.log(err)
            })
        }
      },
      getPositionById(arr, id) {
        for (let i = 0; i < arr.length; i++) {
          if (arr[i].data.id === id) {
            return i
          }
        }
        return -1
      }
    }
  }
</script>

<style lang="scss" scoped>
  .catalog {
    min-width: 238px;
    background: #a1e1f9;
    position: relative;

    .title {
      width: 100%;
      height: 76px;
      line-height: 80px;
      text-align: center;
      background: rgba(62, 197, 239, 0.5);
      // background-color: #6dd2f4;
      margin: 0;
      text-align: center;

      font-size: 20px;
      font-family: PingFangSC-Semibold, PingFang SC;
      font-weight: 600;
      color: rgba(255, 255, 255, 1);

      img {
        width: 22px;
        position: relative;
        top: 3px;
        left: 10px;
        cursor: pointer;
      }
    }

    .el-icon-more {
      position: absolute;
      right: 5px;
      top: 15px;
      color: rgba(155, 155, 155, 0.5);
      transform: rotate(90deg);
    }
  }
</style>

<style lang="scss">
  .catalog {
    .el-tree {
      padding: 8px 12px 0 8px;
      background: rgba(255, 255, 255, 0);

      .is-current {
        & > .el-tree-node__content,
        & > .el-tree-node__content .el-icon-more {
          color: #2ca1d5;
        }
      }

      .el-tree-node {
        margin-bottom: 8px;
        border-radius: 5px;
        overflow: hidden;
        background: rgba(255, 255, 255, 1);
        position: relative;

        .el-tree-node__content {
          height: 47px;
          box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.1);
          position: relative;
          padding-right: 30px;
          // z-index: 9999;

        }

        .el-tree-node__children {
          .el-tree-node {
            border-radius: 0;
            margin: 0;

            .el-tree-node__content {
              height: 40px;
              border-bottom: 1px solid #e9e8e8;
              position: static;
              // margin: 0 20px;
              box-shadow: none;
              // padding-left: 10px !important;

              i.el-icon-tickets {
                font-size: 12px;
                color: #d0d0d0;
              }

              .el-icon-more {
                top: 14px;
              }
            }
          }
        }
      }
    }

    .el-scrollbar {
      height: calc(100% - 80px);
    }

    .drag-line {
      cursor: ew-resize !important;
    }
  }
</style>
